import javax.microedition.lcdui.*;
import javax.microedition.rms.*;

public class Table extends CustomItem implements ItemCommandListener 
{
		private static final Command CMD_EDIT = new Command("Edit", Command.ITEM, 1);
		private static final Command CMD_SAVE = new Command("Save", Command.ITEM, 1);
		private static final Command CMD_DELETE = new Command("Delete", Command.ITEM, 1);
		private static final Command CMD_COPY = new Command("Copy", Command.ITEM, 1);
		private static final Command CMD_PASTE = new Command("Paste", Command.ITEM, 1);
		private static final Command CMD_CUT = new Command("Cut", Command.ITEM, 1);
		private static final Command CMD_GOTO = new Command("Goto", Command.ITEM, 1);
		private static final Command CMD_FIND = new Command("Find", Command.ITEM, 1);
		private Display display;

		public int currentRow ;
		public int currentColumn ;
		public int leftColumn=0;
		public int rightColumn =0;
		public int topRow =0;
		public int bottomRow = 0;
		public int rows = 0;
		public int columns = 0;
		public String data[][] = new String[925][125] ;
		private int unitHeight =0;
		private int unitWidth =0;
		private int borderWidth =0;
		private int borderHeight =0;
		private int tableWidth =0;
		private int tableHeight = 0;
		private int width = 0;
		private int height = 0;
		private Font font;
		private SpreadSheet parent;
		private boolean traversalState = false;
		private int textBoxHeight = 20;
		private int padding = 3;
		private RecordStore rs;
		private String copyData = "";
		private String recordSetName = null;

		public Table(String title, Display d,SpreadSheet sheet, int width,int height)
		{
			super(title);
			display = d;
			setDefaultCommand(CMD_SAVE);
			setDefaultCommand(CMD_DELETE);
			setDefaultCommand(CMD_CUT);
			setDefaultCommand(CMD_COPY);
			setDefaultCommand(CMD_PASTE);
			setDefaultCommand(CMD_GOTO);
			setDefaultCommand(CMD_FIND);
			setDefaultCommand(CMD_EDIT);
			setItemCommandListener(this);

			parent = sheet;
			this.width = width;
			this.height = height;

			borderHeight = 11;
			borderWidth = 17;

			tableHeight = height - borderHeight - textBoxHeight - padding -15 ;
			tableWidth = width - borderWidth;

			for (int i = 0; i< 925; i++)
			{
				for(int j=0; j<125;j++)
				{
					data[i][j] = "";
				}
			}
					
	
			rows = 8;
			columns = 3;

			unitHeight = tableHeight/rows;
			unitWidth = tableWidth/columns;

			topRow = 0;
			leftColumn =0;
			bottomRow = rows -1 ;
			rightColumn = columns -1;

			currentRow =1;
			currentColumn = 1;
    }


	protected int getMinContentHeight() 
	{
		return height - 10;
	}

	protected int getMinContentWidth() 
	{
        return width;
    }

    protected int getPrefContentHeight(int width) 
	{
        return height - 10;
    }

    protected int getPrefContentWidth(int height) 
	{
        return width;
    }

	public void paint(Graphics g, int w, int h)
	{ 
		font = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_PLAIN, Font.SIZE_SMALL);
		g.setFont(font);

		// Draw rectangle at the top as textBox
		g.drawRect(0,0,width-4,20);

		// Draw vertical border
		for(int borderColumn =0; borderColumn < rows;borderColumn++)
		{
			g.setColor(150,150,150);
			g.fillRect(0,unitHeight*borderColumn+borderHeight+padding+textBoxHeight, borderWidth,unitHeight*(borderColumn+1));
			g.setColor(0,0,0);
			g.drawString(""+(topRow+borderColumn),0,unitHeight*borderColumn+borderHeight+padding+textBoxHeight, Graphics.LEFT | Graphics.TOP);
		}
		
		//Draw horzontal border
		for(int borderRow =0; borderRow<columns; borderRow++)
		{
			g.setColor(150,150,150);
			g.fillRect(unitWidth*borderRow+borderWidth,padding+textBoxHeight,unitWidth*(borderRow+1),borderHeight);
			g.setColor(0,0,0);
			g.drawString(""+(leftColumn+borderRow),unitWidth*borderRow+borderWidth,padding+textBoxHeight,Graphics.LEFT | Graphics.TOP);
		}

		//Fill gap at the top
		g.setColor(150,150,150);
		g.fillRect(0,padding+textBoxHeight,borderWidth,borderHeight);

		// Draw table
		g.setColor(200,200,200);
		for(int row =0; row < rows; row++)
		{	
			for(int column =0; column < columns; column++)
			{
				g.drawRect(column*unitWidth+borderWidth,row*unitHeight+borderHeight+padding+textBoxHeight,unitWidth,unitHeight);
			}
		}

		// Fill selected cell
		g.setColor(81,223,253);
		g.fillRect((currentColumn-leftColumn)*unitWidth + borderWidth + 1,(currentRow-topRow)*unitHeight + borderHeight + +padding+textBoxHeight + 1,unitWidth-1,unitHeight-1);

		// Fill corresponding border
		g.setColor(177,79,46);
		g.fillRect(0,(currentRow-topRow)*unitHeight + borderHeight +padding+textBoxHeight ,borderWidth,unitHeight);
		g.fillRect((currentColumn-leftColumn)*unitWidth + borderWidth ,padding+textBoxHeight,unitWidth,borderHeight);
		g.setColor(0,0,0);
		g.drawString(""+(currentRow),0,(currentRow-topRow)*unitHeight + borderHeight + padding+textBoxHeight , Graphics.LEFT | Graphics.TOP);
		g.drawString(""+(currentColumn),(currentColumn-leftColumn)*unitWidth + borderWidth,padding+textBoxHeight,Graphics.LEFT | Graphics.TOP);

		g.setColor(0,0,0);
		for (int i = topRow,k=0; i<= bottomRow; i++,k++)
		{
			for(int j=leftColumn,l=0; j<= rightColumn; j++,l++)
			{
				String cellValue = data[i][j];
				if(cellValue.length() > 9)
					g.drawString(data[i][j].substring(0,6)+"...", l*unitWidth + borderWidth + 1,k*unitHeight+borderHeight+padding+textBoxHeight, Graphics.LEFT | Graphics.TOP);
				else
					g.drawString(data[i][j], l*unitWidth + borderWidth + 1,k*unitHeight + borderHeight+padding+textBoxHeight, Graphics.LEFT | Graphics.TOP);
				if(i == currentRow && j == currentColumn)
				{
					int textWidth =0;
					int chars= 0;
					for(; chars<cellValue.length();chars++)
					{
						textWidth += font.charWidth(cellValue.charAt(chars));
						if(textWidth > width - 15)
						{
							break;
						}
					} 
					if(textWidth > tableWidth)
						g.drawString(data[i][j].substring(0,chars-3)+"...",2,2, Graphics.LEFT | Graphics.TOP);	
					else
						g.drawString(data[i][j],2,2, Graphics.LEFT | Graphics.TOP);						
				}
			}
		}
	}

    public boolean traverse(int dir, int viewportWidth, int viewportHeight, int[] visRect_inout)
	{
		if(traversalState == false)
		{
			traversalState = true;
			return true;
		}

		int action = dir;
		if (action == Canvas.UP) 
		{
			if(currentRow > 0)
				currentRow --;	
			if(currentRow < topRow)
			{
				topRow = currentRow ;
				bottomRow = topRow + (rows-1);
			}
			repaint();							
		} 
		else if (action == Canvas.DOWN) 
		{
			if(currentRow < 924)		
				currentRow ++;
			if(bottomRow < currentRow)
			{
				bottomRow = currentRow;
				topRow = bottomRow - (rows-1);
			}
			repaint();	
		} 
		else if (action == Canvas.LEFT) 
		{
			if(currentColumn > 0)
			 	currentColumn --;
			if(currentColumn < leftColumn)
			{
				leftColumn = currentColumn;
				rightColumn = leftColumn + (columns-1);
			}
			repaint();	
		} 
		else if (action == Canvas.RIGHT) 
		{
			if(currentColumn < 124)
				 currentColumn ++;
			if(rightColumn < currentColumn)
			{
				rightColumn = currentColumn;
				leftColumn = rightColumn - (columns -1);
			}
			repaint();	
		} 
		else
		{
			return true;
		}
		
		return true;
    }

    public void setText(String text) 
	{
		data[currentRow][currentColumn] = text;
	    repaint();
		traversalState = false;
    }

	public void openRecordStore(String name)
	{
		recordSetName = name;

		// Open record store
		try
		{
			rs = RecordStore.openRecordStore(recordSetName,true);	

			for (int i = 0; i< 925; i++)
			{
				for(int j=0; j<125;j++)
				{
					data[i][j] = "";
				}
			}
			
			int records = rs.getNumRecords();
			for(int k=1; k <= records; k++)
			{
				byte buffer[] = rs.getRecord(k);
				String recordData = new String(buffer);
				int index1 = recordData.indexOf(',');
				int index2 = recordData.indexOf(',',index1+1);
				String rowValue = recordData.substring(0,index1);
				String columnValue = recordData.substring(index1+1,index2);	
				int row = Integer.parseInt(rowValue);
				int column = Integer.parseInt(columnValue);
				String currentRecordData = recordData.substring(index2+1,recordData.length());
				data[row][column] = currentRecordData;
			}

			rs.closeRecordStore();
		}
		catch(RecordStoreNotOpenException exc)
		{
		}
		catch(InvalidRecordIDException exc)
		{
		}	
		catch(RecordStoreException exc)
		{
		}
		catch(NullPointerException exc)
		{
		}
	}

	public void saveRecord(String name)
	{
		recordSetName = name;
			try
			{
					rs = RecordStore.openRecordStore(recordSetName,true);

					// Add all records
					byte buffer[];
					for(int ii=0;ii<925;ii++)
					{
						for(int j=0;j<125;j++)
						{
							String currentData = data[ii][j];
							buffer = currentData.getBytes();
							if(buffer.length != 0)
							{
								currentData = ""+ii+","+j+","+currentData;
								buffer = currentData.getBytes();
								rs.addRecord(buffer,0,buffer.length);
							}
						}
					}

					rs.closeRecordStore();

					rs = RecordStore.openRecordStore("SpreadSheet",true);
					buffer = recordSetName.getBytes();
					rs.addRecord(buffer,0,buffer.length);
	
					rs.closeRecordStore();
			}
			catch(RecordStoreNotOpenException exc)
			{
			}
			catch(InvalidRecordIDException exc)
			{
			}	
			catch(RecordStoreException exc)
			{
			}
	}

    public void findText(String recordData) 
	{
		if(recordData.equals("No match found"))
		{
			return ;
		}
		int index1 = recordData.indexOf(',');
		int index2 = recordData.indexOf('-',index1+1);
		String rowValue = recordData.substring(0,index1);
		String columnValue = recordData.substring(index1+1,index2);	
		int row = Integer.parseInt(rowValue);
		int column = Integer.parseInt(columnValue);
		
		setRowColumn(row,column);
    }

    public void setRowColumn(int row,int column) 
	{

		currentRow = row;
		currentColumn = column;

			leftColumn = currentColumn - columns/2;
			rightColumn = currentColumn + columns/2;
			topRow = currentRow - rows/2;
			bottomRow = currentRow + rows/2;

			if(row > (924 - rows/2))
			{
				topRow = 924 - rows + 1;
				bottomRow = 924;
			}
			if(row < rows/2)
			{
				topRow = 0;
				bottomRow = rows-1;
			}
			if(column < columns/2)
			{
				leftColumn = 0;
				rightColumn = columns - 1;
			}
			if(column > (124 - columns/2))
			{
				leftColumn = 124 - columns + 1;
				rightColumn = 124;
			}

	      repaint();
		traversalState = false;
    }

    public void commandAction(Command c, Item i) 
	{
		if (c == CMD_EDIT) 
		{
			TextInput textInput = new TextInput(data[currentRow][currentColumn], this, display);
            display.setCurrent(textInput);
        }
        if (c == CMD_DELETE) 
		{
			data[currentRow][currentColumn]= "";
			repaint();
        }
        if (c == CMD_CUT) 
		{
			copyData = data[currentRow][currentColumn];
			data[currentRow][currentColumn] = "";
			repaint();
        }
        if (c == CMD_COPY) 
		{
			copyData = data[currentRow][currentColumn];
        }
        if (c == CMD_PASTE) 
		{
			data[currentRow][currentColumn]= data[currentRow][currentColumn] + copyData;
			repaint();
        }
        if (c == CMD_GOTO) 
		{
            GotoForm gotoForm = new GotoForm(this, display);
            display.setCurrent(gotoForm);
        }
        if (c == CMD_FIND) 
		{
            FindForm findForm = new FindForm(this, display);
            display.setCurrent(findForm);
        }
        if (c == CMD_SAVE) 
		{
			try
			{
				if(recordSetName == null)
				{
					TextInput textInput = new TextInput("Save as", this, display,10);
			        display.setCurrent(textInput);
				}
				else
				{
					// Delete all records
					RecordStore.deleteRecordStore(recordSetName);
					rs = RecordStore.openRecordStore(recordSetName,true);

					// Add all records
					byte buffer[];
					for(int ii=0;ii<925;ii++)
					{
						for(int j=0;j<125;j++)
						{
							String currentData = data[ii][j];
							buffer = currentData.getBytes();
							if(buffer.length != 0)
							{
								currentData = ""+ii+","+j+","+currentData;
								buffer = currentData.getBytes();
								rs.addRecord(buffer,0,buffer.length);
							}
						}
					}

					rs.closeRecordStore();
				}
			}
			catch(RecordStoreNotOpenException exc)
			{
			}
			catch(InvalidRecordIDException exc)
			{
			}	
			catch(RecordStoreException exc)
			{
			}
		}
    }
}
